package com.liy.teaching.core.config;

import com.liy.teaching.core.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;


/**
 *
 *  1.基于角色的权限访问控制RBAC（role-based access control）
 *    是以角色为中心进行的访问控制，判断当前请求用户 是否具有指定的角色, 是粗粒度的, 不建议采用;
 *
 * </p>
 *
 *　2.基于资源的权限访问控制RBAC（resource-based access control）
 *    是以资源为中心进行的访问控制，是以权限码(资源码) 来判断当前请求的用户是否具有指定的权限码(资源码) 细粒度, 建议采用;
 *
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .authorizeRequests()   // 配置请求地址的权限
                .antMatchers("/test01").permitAll()   // 所有用户可访问,无需登录认证, @PermitAll 功能一样

                // 基于 权限码(资源码)
                .antMatchers("/test02").hasAnyAuthority("sys.user.add","")  // 含有这里指 权限码(资源码)数组中 任何一个即可
                .antMatchers("/test03").access("hasAnyAuthority('sys.user.add')")

                .antMatchers("/test04").hasAuthority("sys.user.delete")     // 必须含有指定的 权限码(资源码)
                .antMatchers("/test05").access("hasAuthority('sys.user.delete')")


                // 基于角色
                .antMatchers("/test06").hasAnyRole("admin","manager")  // 含有这里指 角色数组中 任何一个即可
                .antMatchers("/test07").access("hasAnyRole('ROLE_admin')")

                .antMatchers("/test08").hasRole("admin")   // 必须含有指定的 角色
                .antMatchers("/test09").access("hasRole('ROLE_admin')")

                .anyRequest().authenticated()  // 任何请求，访问的用户都需要经过认证
                .and()
                .formLogin() // 设置 Form 表单登陆
                .permitAll()
                .and()
                .logout() // 配置退出相关
                .permitAll()
                .and()
                .csrf()
                .disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                //inMemoryAuthentication()// 使用内存中的 InMemoryUserDetailsManager
                .userDetailsService(userService)
                .passwordEncoder(NoOpPasswordEncoder.getInstance()); // 不使用 PasswordEncoder 密码编码器
        //.withUser("admin").password("admin").roles("ADMIN") // 配置 admin 用户
        //.and().withUser("user").password("user").roles("NORMAL");// 配置 normal 用户
    }
}
